package com.design.patterns.list.command;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 命令发布者
 * @author Wangzhiwen
 */
public class Invoker {

    // 聚合命令，可以维护一个命令队列（集合）

    // 命令集合
    private Map<Object,Command> commands;

    // 撤销命令
    private Command undoCommand;
    // 执行命令
    private Command executeCommand;

    // 初始化命令列表
    public Invoker() {
        commands = new LinkedHashMap<>();
        executeCommand = InvalidCommand.getInstance();
        undoCommand = InvalidCommand.getInstance();
    }

    // 设置一组命令
    public void setCommands(Command ...commands){
        for (Command command : commands) {
            this.commands.put(command.commandIdentification(),command);
        }
    }

    // 设置单个命令
    public void setCommands(Command command){
        this.commands.put(command.commandIdentification(),command);
        this.executeCommand = command;
        this.undoCommand = command;
    }

    public void executeCommand(Object commandIdentification){
        if (commands.containsKey(commandIdentification)){
            commands.get(commandIdentification).execute();
            undoCommand = commands.get(commandIdentification);
        }
    }

    public void executeCommand(){
        // 执行命令
        executeCommand.execute();
    }

    public void undoCommand(Object commandIdentification){
        if (commands.containsKey(commandIdentification)){
            commands.get(commandIdentification).undo();
            undoCommand = commands.get(commandIdentification);
        }
    }

    public void undoCommand(){
        undoCommand.undo();
    }

    // 执行所有命令
    public void executeCommands(){
        for (Command command : commands.values()) {
            command.execute();
        }
    }

    // 撤销所有命令
    public void undoCommands(){
        for (Command command : commands.values()) {
            command.undo();
        }
    }


    public void cleanCommands(){
        commands.clear();
        executeCommand = InvalidCommand.getInstance();
        undoCommand = InvalidCommand.getInstance();
    }
}
